package net.oschina.esb.webmvc.filter;

import net.oschina.esb.webmvc.context.ContextHolder;
import net.oschina.esb.webmvc.util.RequestUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.web.context.ServletContextAware;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Easy Spring Boot Root Filter
 *
 * @author Arvin
 * @time 2018/3/15 19:51
 */
public class EsbRootFilter implements Filter, EnvironmentAware, ServletContextAware, InitializingBean {

    private final Logger logger = LoggerFactory.getLogger(EsbRootFilter.class);

    private Environment environment;

    private ServletContext servletContext;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        logger.info("EsbRootFilter init......");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        try {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;

            MDC.put(httpServletRequest.getServletPath(), RandomStringUtils.random(10, true, true) + "," + RequestUtil.getClientIp(httpServletRequest));

            HttpServletRequest wrapperRequest = new EsbRootWrapper((HttpServletRequest) request, (HttpServletResponse) response);

            chain.doFilter(wrapperRequest, response);
        } finally {
            MDC.clear();
        }

    }

    @Override
    public void destroy() {
        logger.info("EsbRootFilter destroy......");
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        ContextHolder.init(servletContext, environment);
    }
}
